/*
 * This is the main activity which appears when first starting the app. Displays a button for initiating 
 * the scanning for Bluetooth low-energy devices. It shows devices of all types and calls HeartRateActivity
 * when the user decides to connect to one of the detected devices.
 */


package jens.nordmark.smartheartratemonitor;

import java.util.ArrayList;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity{
	
	public final static String HEARTRATE_DEVICE = "jens.nordmark.smartheartratemonitor";
	
	private ArrayList<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
	private static int SCAN_TIME = 1000;
	private Handler myHandler = new Handler();
    private BluetoothAdapter myBluetoothAdapter;
    private ListView theListView;
    private DeviceListAdapter adapter = new DeviceListAdapter();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		theListView = (ListView) findViewById(R.id.listview);
		
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        myBluetoothAdapter = bluetoothManager.getAdapter();

        theListView.setAdapter(adapter);
        theListView.addHeaderView(adapter.getHeader());
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
	
	public void onClick(View view){
		this.scanLeDevice();
	}
	
	/*
	 * This function initiates the scan for BLE devices. The scan is limited in time to SCAN_TIME.
	 */
    private void scanLeDevice() {
    	 myHandler.postDelayed(new Runnable() {
             @Override
             public void run() {
                 myBluetoothAdapter.stopLeScan(myLeScanCallback);
             }
         }, SCAN_TIME);

         myBluetoothAdapter.startLeScan(myLeScanCallback);
    }
    
    /*
     * Implements the relevant callback for LE scanning.
     */
    private BluetoothAdapter.LeScanCallback myLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {

    	/*
    	 * When a device is found, check if it is in the ListArray devices, otherwise add it and notify the
    	 * adapter.
    	 */
        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                	if(!devices.contains(device)){
                		devices.add(device);
                		adapter.notifyDataSetChanged();
                	}
                }
            });
        }
    };
    
    /*
     * This is an adapter that is used to dynamically display a list of the devices detected thus far.
     * It also displays a connect button for each device.
     */
    private class DeviceListAdapter extends BaseAdapter {

    	/*
    	 * Returns a fourth of the current display width.
    	 */
		@SuppressWarnings("deprecation")
		private int getChildWidth() {
			Display display = getWindowManager().getDefaultDisplay();
		    int displayWidth = (display.getWidth());
			int childWidth = displayWidth/4;
			return childWidth;
		}
		
		/*
		 * Returns the number of devices currently discovered.
		 */
		@Override
		public int getCount() {
			return devices.size();
		}

		/*
		 * Returns the device at position n in the list of devices.
		 */
		@Override
		public Object getItem(int n) {
			return devices.get(n);
		}

		/*
		 * Returns the hashcode for the device at position n in the list of devices.
		 */
		@Override
		public long getItemId(int n) {
			return devices.get(n).hashCode();
		}

		/*
		 * Generates the views displaying device information. Four columns: name, type, address,
		 * connect-button.
		 */
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			LinearLayout myDeviceView = new LinearLayout(getBaseContext());
			TextView nameView = new TextView(getBaseContext());
			nameView.setText(devices.get(position).getName());
			nameView.setWidth(getChildWidth());
			myDeviceView.addView(nameView);
			TextView typeView = new TextView(getBaseContext());
			typeView.setText(String.valueOf((devices.get(position).getType())));
			typeView.setWidth((int) (getChildWidth()*0.5));
			myDeviceView.addView(typeView);
			TextView addressView = new TextView(getBaseContext());
			addressView.setText(devices.get(position).getAddress());
			addressView.setWidth((int) (getChildWidth()*1.5));
			myDeviceView.addView(addressView);
			Button connectButton = new Button(getBaseContext());
			connectButton.setText("Connect");
			connectButton.setId(position+1000);
			connectButton.setOnClickListener(connectButtonListener);
			connectButton.setWidth(getChildWidth());
			myDeviceView.addView(connectButton);
			return myDeviceView;
		}
		
		/*
		 * Generates the header for the table. Four columns: name, type, address and empty.
		 */
		public View getHeader(){
			LinearLayout myHeaderView = new LinearLayout(getBaseContext());
			TextView nameView = new TextView(getBaseContext());
			nameView.setText("Name");
			nameView.setWidth(getChildWidth());
			myHeaderView.addView(nameView);
			TextView typeView = new TextView(getBaseContext());
			typeView.setText("Type");
			typeView.setWidth((int) (getChildWidth()*0.5));
			myHeaderView.addView(typeView);
			TextView addressView = new TextView(getBaseContext());
			addressView.setText("Address");
			addressView.setWidth((int) (getChildWidth()*1.5));
			myHeaderView.addView(addressView);		
			return myHeaderView;
		}
    }
    
    /*
     * Handles onClick-events from the connect-buttons.
     */
    View.OnClickListener connectButtonListener = new View.OnClickListener() {
		
    	/*
    	 * Starts a HeartRateActivity with the chosen device as parameter.
    	 */
		@Override
		public void onClick(View v) {
			int ID = v.getId();
			Intent intent = new Intent(getBaseContext(), HeartRateActivity.class);
			intent.putExtra(HEARTRATE_DEVICE, devices.get(ID-1000).getAddress());
			startActivity(intent);
			Log.d("MainActivity","Starting HeartrateActivity");
		}
	};
}
